#include "showcamera.h"

#include "rga/im2d.h"
#include "rga/RgaUtils.h"
#include "rga/RgaApi.h"

// 构造函数：初始化OpenGL相关对象
showcamera::showcamera(QWidget *parent)
    : QOpenGLWidget(parent)          // 继承OpenGL渲染组件
    , VBO(QOpenGLBuffer::VertexBuffer) // 创建顶点缓冲对象（Vertex Buffer）
    , texture(QOpenGLTexture::Target2D) // 创建2D纹理对象
    , detectionVBO(QOpenGLBuffer::VertexBuffer)
{

}

// 初始化OpenGL环境
void showcamera::initializeGL()
{
    initializeOpenGLFunctions(); // 初始化Qt封装的OpenGL函数
    glClearColor(0,0,0,0);       // 设置清屏颜色为黑色

    /*-- 顶点数组对象(VAO)初始化 --*/
    VAO.create(); // 创建VAO（用于存储顶点属性配置）
    VAO.bind();

    /*-- 顶点缓冲(VBO)设置 --*/
    VBO.create();  // 创建VBO
    VBO.bind();     // 绑定VBO
    // 定义包含位置和纹理坐标的顶点数据（已翻转Y轴纹理坐标）
    float vertex[] = {
        // 位置坐标      纹理坐标
        -1.0f, -1.0f,   0.0f, 1.0f,  // 左下角顶点
        -1.0f,  1.0f,   0.0f, 0.0f,  // 左上角顶点
        1.0f, -1.0f,   1.0f, 1.0f,  // 右下角顶点
        1.0f,  1.0f,   1.0f, 0.0f   // 右上角顶点
    };
    VBO.allocate(vertex, sizeof(vertex)); // 将顶点数据上传至GPU

    /*-- 着色器程序配置 --*/
    // 加载并编译顶点/片段着色器
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/texture_camera.vsh");
    shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/texture_camera.fsh");
    shaderProgram.link(); // 链接着色器程序

    // 配置顶点属性指针
    shaderProgram.bind(); // 绑定着色器程序
    // 位置属性（索引0，每元素2个float，步长4个float）
    shaderProgram.setAttributeBuffer(0, GL_FLOAT, 0, 2, 4*sizeof(float));
    // 纹理坐标属性（索引1，偏移2个float，每元素2个float）
    shaderProgram.setAttributeBuffer(1, GL_FLOAT, 2*sizeof(float), 2, 4*sizeof(float));
    // 启用属性数组
    shaderProgram.enableAttributeArray(0);
    shaderProgram.enableAttributeArray(1);
    shaderProgram.release(); // 解绑着色器

    /*-- 纹理对象初始化 --*/
    texture.create(); // 创建纹理
    texture.setWrapMode(QOpenGLTexture::ClampToEdge); // 设置边缘截取模式
    texture.setMinMagFilters(QOpenGLTexture::Linear, QOpenGLTexture::Linear); // 设置过滤方式

    // === 2. 创建检测框渲染管道 ===
    detectionShader.addShaderFromSourceCode(QOpenGLShader::Vertex,":/detection_shader.vsh");

    detectionShader.addShaderFromSourceCode(QOpenGLShader::Fragment,":/detection_shader.fsh");

    if (!detectionShader.link()) {
        qWarning() << "Detection shader link error:" << detectionShader.log();
    }

    detectionVBO.create();
    detectionVBO.setUsagePattern(QOpenGLBuffer::DynamicDraw);
}

// 渲染函数（每帧调用）
void showcamera::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT); // 清空颜色缓冲区

    if(texture.isCreated()) {
        shaderProgram.bind();      // 绑定着色器程序
        texture.bind(0);           // 绑定纹理到纹理单元0
        shaderProgram.setUniformValue("texture", 0); // 传递纹理单元给着色器

        QOpenGLVertexArrayObject::Binder vaoBinder(&VAO); // 绑定VAO
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // 绘制四边形（4个顶点）

        texture.release();        // 解绑纹理
        shaderProgram.release();  // 解绑着色器
    }


    // === 2. 渲染检测框 ===
    if (detectionVertexCount > 0 && detectionsInitialized) {
        glLineWidth(2.0f); // 设置线宽

        detectionShader.bind();
        detectionShader.setUniformValue("boxColor", QVector4D(1.0f, 0.0f, 0.0f, 1.0f)); // 红色

        {
            detectionVBO.bind();
            glEnableVertexAttribArray(0);
            glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr);

            // 使用线段绘制检测框（每个矩形需要8个顶点形成4条线）
            glDrawArrays(GL_LINES, 0, detectionVertexCount);

            glDisableVertexAttribArray(0);
            detectionVBO.release();
        }

        detectionShader.release();
    }


}

// 窗口尺寸变化回调
void showcamera::resizeGL(int w, int h)
{
    glViewport(0,0,w,h); // 设置视口与窗口同尺寸
}

// 接收并更新摄像头数据
void showcamera::setCameraData(const char* data, int width, int height) {
    makeCurrent();
    QSize imgeSize(width, height);


    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

    texture.bind();
    if (!textureInitialized || lastImageSize != imgeSize) {
        texture.setSize(width, height);
        texture.setFormat(QOpenGLTexture::RGBFormat);
        texture.allocateStorage();
        textureInitialized = true;
        lastImageSize = imgeSize;
    }

    // 直接使用RGA内存更新纹理
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height,
                    GL_RGB, GL_UNSIGNED_BYTE, data); // ⭐直接传入data

    update();
    doneCurrent();
}

void showcamera::setDetections(const std::vector<QRectF> &detections)
{
    if (detections.empty()) {
        detectionVertexCount = 0;
        update();
        return;
    }

    // 生成检测框顶点数据
    std::vector<float> vertices;
    vertices.reserve(detections.size() * 8); // 每个矩形4条线，每条线2个顶点

    const float scaleX = 2.0f / lastImageSize.width();
    const float scaleY = 2.0f / lastImageSize.height();

    for (const auto& rect : detections) {
        // 转换为OpenGL标准化坐标
        float x1 = rect.left() * scaleX - 1.0f;
        float y1 = 1.0f - rect.top() * scaleY; // 翻转Y轴
        float x2 = (rect.left() + rect.width()) * scaleX - 1.0f;
        float y2 = 1.0f - (rect.top() + rect.height()) * scaleY;

        // 绘制矩形四条边
        // 上边
        vertices.push_back(x1); vertices.push_back(y1);
        vertices.push_back(x2); vertices.push_back(y1);

        // 右边
        vertices.push_back(x2); vertices.push_back(y1);
        vertices.push_back(x2); vertices.push_back(y2);

        // 下边
        vertices.push_back(x2); vertices.push_back(y2);
        vertices.push_back(x1); vertices.push_back(y2);

        // 左边
        vertices.push_back(x1); vertices.push_back(y2);
        vertices.push_back(x1); vertices.push_back(y1);
    }

    detectionVertexCount = vertices.size() / 2;

    makeCurrent();
    detectionVBO.bind();
    detectionVBO.allocate(vertices.data(), vertices.size() * sizeof(float));
    detectionVBO.release();
    detectionsInitialized = true;
    doneCurrent();

    update();
}
